﻿using System;
using System.Xml.Serialization;
using PrearrangedChaos.AgileZen.Service.Rest;

namespace PrearrangedChaos.AgileZen.Service.Model
{
    [XmlType(AnonymousType = true)]
    [XmlRoot(ElementName = "story", Namespace = "", IsNullable = false)]
    [ZenRestRequest("projects/{ProjectId}/stories/{StoryId}")]
    public class StoryUpdater : ModelBase, IStoryUpdater
    {
        private IUser _owner;
        private IPhase _phase;
        private StoryColor? _color;
        private DateTime? _deadline;
        private string _priority;
        private string _size;
        private StoryStatus? _status;
        private string _text;
        private string _blockedReason;
        private string _details;

        /// <remarks/>
        [XmlElement(ElementName = "color")]
        public string ColorXmlElement
        {
            get
            {
                return this.Color == null ? null : this.Color.ToString().ToLower();
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                    this.Color = StoryColor.Grey;
                else
                    this.Color = (StoryColor)Enum.Parse(typeof (StoryColor), value, true);

                this.Unmodified("color");
            }
        }

        public bool ColorXmlElementSpecified { get { return this.IsModified("color"); } }

        [XmlIgnore]
        public StoryColor? Color
        {
            get { return _color; }
            set
            {
                if (_color == value)
                    return;

                _color = value;
                this.Modified("color");
            }
        }

        [XmlElement(ElementName = "deadline")]
        public DateTime? DeadlineXmlElement
        {
            get { return _deadline; }
            set
            {
                _deadline = value;
                this.Unmodified("deadline");
            }
        }


        [XmlIgnore]
        public DateTime? Deadline
        {
            get { return _deadline; }
            set
            {
                if (_deadline == value)
                    return;

                _deadline = value;
                this.Modified("deadline");
            }
        }

        public bool DeadlineXmlElementSpecified { get { return this.IsModified("deadline"); } }

        /// <remarks/>
        [XmlElement(ElementName = "owner")]
        public User OwnerXmlElement
        {
            get { return _owner as User; }
            set
            {
                _owner = value;
                this.Unmodified("owner");
            }
        }

        /// <remarks/>
        [XmlIgnore]
        public IUser Owner
        {
            get { return _owner; }
            set
            {
                _owner = value;
                this.Modified("owner");
            }
        }

        public bool OwnerXmlElementSpecified { get { return this.IsModified("owner"); } }

        /// <remarks/>
        [XmlElement(ElementName = "phase")]
        public Phase PhaseXmlElement
        {
            get { return _phase as Phase; }
            set
            {
                _phase = value;
                this.Unmodified("phase");
            }
        }

        /// <remarks/>
        [XmlIgnore]
        public IPhase Phase
        {
            get { return _phase; }
            set
            {
                if (_phase == value)
                    return;

                _phase = value;
                this.Modified("phase");
            }
        }

        public bool PhaseXmlElementSpecified { get { return this.IsModified("phase"); } }

        /// <remarks/>
        [XmlElement(ElementName = "priority", IsNullable = true)]
        public string PriorityXmlElement
        {
            get { return _priority; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _priority = value;
                else
                    _priority = null;

                this.Unmodified("priority");
            }
        }

        [XmlIgnore]
        public string Priority
        {
            get { return _priority; }
            set
            {
                if (_priority == value)
                    return;

                _priority = value;
                this.Modified("priority");
            }
        }

        public bool PriorityXmlElementSpecified { get { return this.IsModified("priority"); } }

        /// <remarks/>
        [XmlElement(ElementName = "size", IsNullable = true)]
        public string SizeXmlElement
        {
            get { return _size; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _size = value;
                else
                    _size = null;
            }
        }

        [XmlIgnore]
        public string Size
        {
            get { return _size; }
            set
            {
                if (_size == value)
                    return;

                _size = value;
                this.Modified("size");
            }
        }

        public bool SizeXmlElementSpecified { get { return this.IsModified("size"); } }

        /// <remarks/>
        [XmlElement(ElementName = "status")]
        public string StatusXmlElement
        {
            get
            {
                return this.Status == null ? null : this.Status.ToString().ToLower();
            }
            set
            {
                this.Status = (StoryStatus)Enum.Parse(typeof(StoryStatus), value, true);
                this.Unmodified("status");
            }
        }

        public bool StatusXmlElementSpecified { get { return this.IsModified("status"); } }


        [XmlIgnore]
        public StoryStatus? Status
        {
            get { return _status; }
            set
            {
                if (_status == value)
                    return;

                _status = value;
                this.Modified("status");
            }
        }

        /// <remarks/>
        [XmlElement(ElementName = "text")]
        public string TextXmlElement
        {
            get { return _text; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _text = value;
                else
                    _text = null;

                this.Unmodified("text");
            }
        }

        [XmlIgnore]
        public string Text
        {
            get { return _text; }
            set
            {
                if (_text == value)
                    return;

                _text = value;
                this.Modified("text");
            }
        }

        public bool TextXmlElementSpecified { get { return this.IsModified("text"); } }

        /// <remarks/>
        [XmlElement(ElementName = "details")]
        public string DetailsXmlElement
        {
            get { return _details; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _details = value;
                else
                    _details = null;

                this.Unmodified("details");
            }
        }

        [XmlIgnore]
        public string Details
        {
            get { return _details; }
            set
            {
                if (_details == value)
                    return;

                _details = value;
                this.Modified("details");
            }
        }

        public bool DetailsXmlElementSpecified { get { return this.IsModified("details"); } }

        [XmlElement(ElementName = "blockedReason")]
        public string BlockedReasonXmlElement
        {
            get { return _blockedReason; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _blockedReason = value;
                else
                    _blockedReason = null;

                this.Unmodified("blockedReason");
            }
        }

        [XmlIgnore]
        public string BlockedReason
        {
            get { return _blockedReason; }
            set
            {
                if (_blockedReason == value)
                    return;

                _blockedReason = value;
                this.Modified("blockedReason");
            }
        }

        public bool BlockedReasonXmlElementSpecified { get { return this.IsModified("blockedReason"); } }
    }
}